package top.tieyan.fs.group.vo;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.google.common.collect.Lists;
import lombok.Data;
import top.tieyan.fs.group.entity.User;

import java.util.List;

/**
 * <document type="freeswitch/xml">
 *   <section name="directory">
 *     <domain name="domain1.awesomevoipdomain.faketld">
 *       <params>
 *         <param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
 *       </params>
 *       <groups>
 *         <group name="default">
 *          <users>
 *           <user id="1004">
 *             <params>
 *               <param name="password" value="some_password"/>
 *             </params>
 *             <variables>
 *       			<variable name="toll_allow" value="domestic,international,local"/>
 *			        <variable name="accountcode" value="1000"/>
 *			        <variable name="user_context" value="default"/>
 *			        <variable name="effective_caller_id_name" value="Extension 1000"/>
 *			        <variable name="effective_caller_id_number" value="1000"/>
 *			        <variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
 *			        <variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
 *			        <variable name="callgroup" value="techsupport"/>
 *			   </variables>
 *           </user>
 *          </users>
 *         </group>
 *       </groups>
 *     </domain>
 *   </section>
 * </document>
 * @author TieYan
 * @date 2018/7/19
 */
@Data
@JacksonXmlRootElement(localName = "document")
public class Directory {
	@JacksonXmlProperty(isAttribute = true)
	private String type = "freeswitch/xml";

	private Section section;

	public static Directory of(User user){
		String dialStrName = "dial-string";
		String dialStrValue = "{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}";

		Directory directory = new Directory();
		Section section = new Section();
		directory.setSection(section);

		Domain domain = new Domain(user.getDomain());
		domain.setParam(Lists.newArrayList(new Param(dialStrName, dialStrValue)));

		Group group = new Group();
		XmlUser xmlUser = new XmlUser(user.getName());
		xmlUser.setParam(Lists.newArrayList(new Param("password", user.getPassword())));
		xmlUser.setVariable(Lists.newArrayList(
				new Variable("toll_allow", "domestic,international,local"),
				new Variable("accountcode", user.getName()),
				new Variable("user_context", "default"),
				new Variable("effective_caller_id_name", "Extension " + user.getName()),
				new Variable("effective_caller_id_number", user.getName()),
				new Variable("outbound_caller_id_name", "$${outbound_caller_name}"),
				new Variable("outbound_caller_id_number", "$${outbound_caller_id}"),
				new Variable("callgroup", "techsupport")
		));
		List<XmlUser> users = Lists.newArrayList(xmlUser);
		group.setUser(users);
		domain.setGroup(Lists.newArrayList(group));

		section.setDomain(domain);

		return directory;
	}

	@Data
	private static class Section{
		@JacksonXmlProperty(isAttribute = true)
		private String name = "directory";

		private Domain domain;
	}

	@Data
	private static class Domain{
		Domain(String name) {
			this.name = name;
		}

		@JacksonXmlProperty(isAttribute = true)
		private String name;

		@JacksonXmlElementWrapper(localName = "params")
		private List<Param> param;

		@JacksonXmlElementWrapper(localName = "groups")
		private List<Group> group;
	}

	@Data
	private static class Param{
		Param(String name, String value) {
			this.name = name;
			this.value = value;
		}

		@JacksonXmlProperty(isAttribute = true)
		private String name;

		@JacksonXmlProperty(isAttribute = true)
		private String value;
	}

	@Data
	private static class Group{
		@JacksonXmlProperty(isAttribute = true)
		private String name = "default";

		@JacksonXmlElementWrapper(localName = "users")
		private List<XmlUser> user;
	}

	@Data
	private static class XmlUser{
		XmlUser(String id) {
			this.id = id;
		}

		@JacksonXmlProperty(isAttribute = true)
		private String id;

		@JacksonXmlElementWrapper(localName = "params")
		private List<Param> param;

		@JacksonXmlElementWrapper(localName = "variables")
		private List<Variable> variable;
	}

	@Data
	private static class Variable{
		public Variable(String name, String value) {
			this.name = name;
			this.value = value;
		}

		@JacksonXmlProperty(isAttribute = true)
		private String name;
		@JacksonXmlProperty(isAttribute = true)
		private String value;
	}
}
